package com.timo.redis.server.impl;

import com.timo.redis.model.ExpireTimeUnit;
import com.timo.redis.server.HashOperationsRedisServer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.hash.HashMapper;
import org.springframework.data.redis.hash.Jackson2HashMapper;
import org.springframework.data.redis.hash.ObjectHashMapper;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Map;

/**
 * @Description: 类的详细说明
 * @Author: timo
 * @Date: 2019/8/28 10:59
 */
@Slf4j
@Service
public class HashOperationsRedisServerImpl implements HashOperationsRedisServer {
    @Resource
    HashOperations<String, byte[], byte[]> hashOperations;

    @Resource
    private Jackson2HashMapper jackson2HashMapper;

    @Resource
    private RedisTemplate redisTemplate;

    HashMapper<Object, byte[], byte[]> hashMapper = new ObjectHashMapper();

    @Override
    public <T> void add(String key, T object) {
        Assert.isTrue(StringUtils.isNotEmpty(key),"key is null");
        Assert.notNull(object,"object is null");

        hashOperations.putAll(key,mappedHash(object));
        expire(key, new ExpireTimeUnit());
    }

    @Override
    public <T> void add(String key, T object, ExpireTimeUnit timeUnit) {
        hashOperations.putAll(key,mappedHash(object));
        expire(key, timeUnit);
    }

    @Override
    public <T> void addList(String key, Collection<T> list) {
        hashOperations.putAll(key,mappedHash(list));
        expire(key, new ExpireTimeUnit());
    }

    @Override
    public <T> void addList(String key, Collection<T> list, ExpireTimeUnit timeUnit) {
        hashOperations.putAll(key, mappedHash(list));
        expire(key, timeUnit);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T get(String key, Class<T> cls) {
        Map<byte[], byte[]> loadedHash = hashOperations.entries(key);
        return (T) hashMapper.fromHash(loadedHash);
    }

    @Override
    public <T> T getList(String key, Class<T> cls) {
        Map<byte[], byte[]> loadedHash = hashOperations.entries(key);
        return (T) hashMapper.fromHash(loadedHash);
    }


    /**
     * 设置过期时间
     *
     * @param key      <br>
     * @param timeUnit <br>
     * @return boolean
     * @Author timo <br/>
     * @Date 2019/8/28 11:59 <br/>
     */
    private boolean expire(String key, ExpireTimeUnit timeUnit){
        try {
            if (!StringUtils.isEmpty(key) && timeUnit != null) {
                redisTemplate.expire(key, timeUnit.getExpire(),timeUnit.getTimeUnit());
                return true;
            }
        } catch (Exception e) {
            log.error("redis hashes set  expire time error: ",e.toString()+e.getMessage(),e);
        }
        return false;
    }
}
